package blog

import (
	"context"
	"strconv"
)

const Appname = "blog"

type BlogService interface {
	// 创建
	CreateBlog(context.Context, *CreateBlogRequest) (*Blog, error)
	// 查询并返回多个blog
	QueryBlog(context.Context, *QueryBlogRequest) (*BlogSet, error)
	// 查询返回一个blog
	DescribeBlog(context.Context, *DescribeBlogRequest) (*Blog, error)
	// 删除
	DeleteBlog(context.Context, *DeleteBlogRequest) error
	// 编辑
	UpdateBlog(context.Context, *UpdateBlogRequest) (*Blog, error)
	// 审核, 审核通过的文章才能被看到
	AuditBlog(context.Context, *AuditBlogRequest) (*Blog, error)
}

type BlogSet struct {
	// blog总数量
	Total int64 `json:"total"`
	// blog切片，来展示多个blog
	Item []*Blog `json:"items"`
}

// 以下结构体中的属性：BlogId string `json:"blog_id"`，为什么用string类型？
// 答：再获取用户请求时，通过c.Param("key")、c.Query("key")等方式，返回的时string类型

func NewBlogSet() *BlogSet {
	return &BlogSet{
		Item: []*Blog{},
	}
}

type QueryBlogRequest struct {
	// 一页的大小，也就是一页有多少行
	PageSize int `json:"page_size"`
	// 当前处于几页
	PageNumber int `json:"page_number"`
	// nil 没有这个过滤条件,为默认条件，表示要查询所有的博客，如果不用指针类型，无法表示nil条件
	// 0   DRAFT 表示草稿状态
	// 1   PUBLISHED 表示已发布状态
	Status *Status `json:"status"`
	// 基于文章标题的关键字搜索
	Keywords string `json:"keywords"`
	// 查询属于哪些用户的博客
	Usernames []string `json:"Usernames"`
}

func NewQueryBlogRequest() *QueryBlogRequest {
	return &QueryBlogRequest{
		PageSize:   10,
		PageNumber: 1,
	}
}

func (q *QueryBlogRequest) ParsePageSize(s string) {
	i, err := strconv.Atoi(s)
	if err == nil {
		q.PageSize = i
	}
}

func (q *QueryBlogRequest) ParsePageNumber(s string) {
	i, err := strconv.Atoi(s)
	if err == nil {
		q.PageNumber = i
	}
}

// 把常量转换成为指针类型
func (q *QueryBlogRequest) SetPoint(s Status) {
	var a = s
	q.Status = &a
}

// 扩展QueryBlogRequest方法，实现偏移量
func (q *QueryBlogRequest) Offset() int {
	return q.PageSize * (q.PageNumber - 1)
}

type DescribeBlogRequest struct {
	BlogId string `json:"blog_id"`
}

func NewDescribeBlogRequest() *DescribeBlogRequest {
	return &DescribeBlogRequest{}
}

type DeleteBlogRequest struct {
	BlogId string `json:"blog_id"`
}

func NewDeleteBlogRequest() *DeleteBlogRequest {
	return &DeleteBlogRequest{}
}

type UpdateBlogRequest struct {
	BlogId string `json:"blog_id"`
	// 更新模式，全量或增量
	UpdateMode UpdateMode
	*CreateBlogRequest
}

func NewUpdateBlogRequest(req *CreateBlogRequest) *UpdateBlogRequest {
	return &UpdateBlogRequest{
		CreateBlogRequest: req,
	}
}

type AuditBlogRequest struct {
	BlogId string `json:"blog_id"`
	// 是否审核
	IsAuditPass bool `json:"is_audit_pass"`
}
